/*
 * Paper.java
 * TCSS 360 
 */
package superConference;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @author Steve Mackey
 * @author Oscar Hong
 * @version 2013/12/5
 */
public class Paper {
	
	private static final String PAPERS_DATA_PATH = "data/papers.ini";

	/**
	 * The id of the paper.
	 */
	private int my_id;
	
	/**
	 * The email address of the author of the paper.
	 */
	private String my_author;

	/**
	 * The status of the paper.
	 */
	private PaperStatus my_status;
	
	/**
	 * The title of the paper.
	 */
	private String my_title;
	
	/**
	 * The email address of the SubProgramChair assigned to this paper.
	 */
	private String my_sub_chair;
	
	/**
	 * A list of reviews to this paper.
	 */
	private List<Review> my_reviews;
	
	/**
	 * Construct a new paper.
	 * @param id the id of the paper
	 * @param author the email of the author of the paper
	 * @param status the status of the paper
	 * @param title the title of the paper
	 * @param file the content of the paper
	 */
	private Paper(int id, String author, PaperStatus status, String title, String subChair){
		
		my_id = id;
		my_author = author;
		my_status = status;
		my_title = title;
		my_sub_chair = subChair;
		my_reviews = new ArrayList<Review>();
	}
	
	/**
	 * Change the file for specific paper id.
	 * @param id the id of the paper
	 * @param source the file of the new paper
	 */
	private static void setFile(int id, File source) {
		File dest = new File("data/papers/"+id+".txt");
		try {
			Files.copy(source.toPath(), dest.toPath());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.getMessage();
		}
	}
	
	/**
	 * Construct a paper with the default status (SUBMITTED) and no sub chair. <br>
	 * This constructor will save the file that passed in to <i>./data/papers/(paper_id).txt</i>.<br>
	 * Author will use this constructor to submit a paper.
	 * @param id the id of the paper
	 * @param author the email of the author of the paper
	 * @param title the title of the paper
	 * @param file the file name of the paper
	 */
	public Paper(User author, String title, File source) {
		this(nextID(), author.getEmail(), PaperStatus.SUBMITTED, title, "");
		setFile(nextID(), source);
		updateMySelf();
	}
	
	/**
	 * Get a list of all papers.
	 * @return a list of all reviews
	 */
	public static List<Paper> getAllPapers() {
		List<Paper> l = new ArrayList<Paper>();
		try {
			Scanner in = new Scanner(new File(PAPERS_DATA_PATH));
			String line = "";
			while(in.hasNextLine()) {
				line = in.nextLine();
				String[] params = line.split(",");
				if (params.length > 1) {
					l.add(loadFromString(line));
				}
			}
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return l;
	}
	
	/**
	 * Get a paper object base on its id.
	 * @param id the id of the paper
	 * @return the Paper object
	 */
	public static Paper getPaperByID(int id) {
		File papers = new File(PAPERS_DATA_PATH);
		Scanner in;
		Paper p = null;
		try {
			in = new Scanner(papers);
			while(in.hasNextLine()) {
				String line = in.nextLine();
				String[] params = line.split(",");
				if(params.length>1 && Integer.parseInt(params[0]) == id) {
					p = loadFromString(line);
				}
			}
			in.close();
		} catch (FileNotFoundException e) {
			e.getMessage();
		}
		return p;
	}
	
	/**
	 * Get a paper object base on its author.
	 * @param author the author of the paper
	 * @return the Paper object
	 */
	public static Paper getPaperByAuthor(String author) {
		File papers = new File(PAPERS_DATA_PATH);
		Scanner in;
		Paper p = null;
		try {
			in = new Scanner(papers);
			while(in.hasNextLine()) {
				String line = in.nextLine();
				String[] params = line.split(",");
				if(params.length>1 && params[1].equals(author)) {
					p = loadFromString(line);
				}
			}
			in.close();
		} catch (FileNotFoundException e) {
			e.getMessage();
		}
		return p;
	}

	/**
	 * Get the id of the paper.
	 * @return the id of the paper
	 */
	public int getId(){
		return my_id;
	}
	
	/**
	 * Get the title of the paper.
	 * @return the title of the paper
	 */
	public String getTitle(){
		return my_title;
	}

	/**
	 * Set the title of the paper.
	 * @param title the title of the paper
	 */
	public void setTitle(String title){
		my_title = title;
		updateMySelf();
	}
	
	/**
	 * Get the email of the author of the paper.
	 * @return the email of the author of the paper
	 */
	public String getAuthor(){
		return my_author;
	}

	/**
	 * Set the email of the author of the paper.
	 * @param author the email of the author of the paper
	 */
	public void setAuther(String author){
		my_author = author;
		updateMySelf();
	}
	
	public String getSubChair() {
		return my_sub_chair;
	}
		
	/**
	 * Check if the email address is the same as the author's.
	 * @param author the user's email address
	 * @return true if the email address is the same as the author's
	 */
	public boolean isAuthor(User author) {
		return author.getEmail() == my_author;
	}
	
	/**
	 * Assign this paper to a SubProgramChair.
	 * @param email the email of the Sub Program Chair
	 */
	public void assignTo(String email) {
		my_sub_chair = email;
		updateMySelf();
	}

	/**
	 * Add a review to this paper.
	 * @param the_review the review to be added
	 */
	public void addReview(Review the_review) {
		my_reviews.add(the_review);
	}
	
	/**
	 * Get a list of reviews of this paper.
	 * @return the list of reviews of this paper
	 */
	public List<Review> getReviews() {
		return my_reviews;
	}
	
	/**
	 * Get the file of this paper.
	 * @return the file of this paper
	 */
	public File getFile() {
		return new File("data/papers/"+my_id+".txt");
	}
	
	/**
	 * Change the file of this paper.
	 * @param source the file of the new paper
	 */
	public void editFile(File source) {
		setFile(my_id, source);
	}
	
	/**
	 * Recommend the paper to the ProgramChair.
	 * @param rec true if you really want to recommend this paper
	 */
	public void rec(boolean rec) {
		if (rec) {
			my_status = PaperStatus.RECOMMENDED;
			updateMySelf();
		}
		
	}

	/**
	 * The ProgramChair accepting the paper.
	 * @param accept true if you really want to accept the paper
	 */
	public void accept(boolean accept) {
		if (accept) {
			my_status = PaperStatus.ACCEPTED;
			updateMySelf();
		}
	}
	
	/**
	 * The string representation of the paper.
	 * @return the string representation of the paper
	 */
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(my_title);
		sb.append(" by ");
		sb.append(my_author);
		sb.append("\tStatus: ");
		sb.append(my_status.getDescription());
		return sb.toString();
	}
	
	/**
	 * Get the next available ID for the paper.
	 * @return the next available ID, or -1 if something unexpected happened
	 */
	private static int nextID() {
		int id = -1;
		try {
			Scanner in = new Scanner(new File(PAPERS_DATA_PATH));
			String line = "";
			while(in.hasNext()) {
				line = in.nextLine();
			}
			// Should be at the last line
			id = Integer.parseInt(line);
			in.close();
		} catch (FileNotFoundException e) {
			e.getMessage();
		}
		return id;
	}
	
	/**
	 * Generate the string for saving in a text file.
	 * @return the string for saving in a text file
	 */
	private String saveToString() {
		StringBuilder sb = new StringBuilder();
		sb.append(my_id);
		sb.append(",");
		sb.append(my_author);
		sb.append(",");
		sb.append(my_status);
		sb.append(",");
		sb.append(my_title);
		sb.append(",");
		sb.append(my_sub_chair);
		return sb.toString();
	}
	
	/**
	 * Generate a Paper from its string representation.
	 * @param s the string representation of a paper
	 * @return the paper
	 */
	private static Paper loadFromString(String s) {
		String[] params = s.split(",");
		int id = Integer.parseInt(params[0]);
		String author = params[1];
		PaperStatus status = PaperStatus.valueOf(params[2]);
		String title = params[3];
		String sub_chair = params[4].toLowerCase();
		
		Paper p = new Paper(id, author, status, title, sub_chair);
		return p;
	}
	
	/**
	 * Update the line of this paper in papers.ini.
	 */
	private void updateMySelf() {
		File papers = new File(PAPERS_DATA_PATH);
		StringBuilder new_papers_text = new StringBuilder();
		Scanner in;
		String line = "";
		try {
			in = new Scanner(papers);
			while(in.hasNextLine()) {
				line = in.nextLine();
				int paper_id = Integer.parseInt(line.split(",")[0]);
				if (paper_id == my_id) {
					new_papers_text.append(saveToString());
					new_papers_text.append("\n");
				} else if (paper_id != nextID()){
					new_papers_text.append(line);
					new_papers_text.append("\n");
				}
				
			}
			in.close();
			int nextID = Integer.parseInt(line);
			if (my_id==nextID) {
				nextID++;
			}
			new_papers_text.append(nextID);
			new_papers_text.append("\n");
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		PrintWriter out;
		try {
			out = new PrintWriter(papers);
			out.write(new_papers_text.toString());
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.getMessage();
		}
	}
}
